#include "dinput.h"
#include "..\common\def.h"
#include "..\engine\engine.h"

HRESULT CDInput9Device::CreateMouseDevice()
{
	try{
		CLog::Write("Creating mouse device: "); 

		if(ISNULL(m_pDInput))
			throw EE_EXCEPTION("No input device")

		if(FAILED(m_pDInput->CreateDevice(GUID_SysMouse, &m_pMouseDevice, NULL)))
			throw EE_EXCEPTION("CreateDevice failed"); 

		if(FAILED(m_pMouseDevice->SetDataFormat(&c_dfDIMouse)))
			throw EE_EXCEPTION("SetDataFormat failed"); 

		if(FAILED(m_pMouseDevice->SetCooperativeLevel(CEngine::GetInstance()->GetWindow()->GetHWnd(), DISCL_BACKGROUND | DISCL_NONEXCLUSIVE)))
			throw EE_EXCEPTION("SetCooperativeLevel failed"); 

		DIPROPDWORD dipdw; 
		dipdw.diph.dwSize = sizeof(DIPROPDWORD); 
		dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); 
		dipdw.diph.dwObj = 0; 
		dipdw.diph.dwHow = DIPH_DEVICE; 
		dipdw.dwData = MOUSE_BUFFER_SIZE; 

		if(FAILED(m_pMouseDevice->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph)))
			throw EE_EXCEPTION("SetProperty failed"); 

		if(FAILED(m_pMouseDevice->Acquire()))
			throw EE_EXCEPTION("Acquire failed"); 

		CLog::WriteLine("Success"); 
		return S_OK; 
	}
	catch(CError::CErrorData error)
	{
		CError::CError(error, ERRORREPORT_LOG);
		m_pMouseDevice = NULL; 
		return E_FAIL; 
	}
}
HRESULT CDInput9Device::ReleaseMouseDevice()
{
	try{
		CLog::Write("Releasing mouse device: "); 

		if(ISNULL(m_pMouseDevice))
		{
			CLog::WriteLine("No mouse device"); 
			return S_OK; 
		}
	
		if(FAILED(m_pMouseDevice->Unacquire()))
			EE_LOGERROR("Failed to unaquire mouse"); 

		if(FAILED(m_pMouseDevice->Release()))
			throw EE_EXCEPTION("Failed to Release mouse"); 
		
		m_pMouseDevice = NULL; 

		CLog::WriteLine("Success"); 
		return S_OK; 
	}
	catch(CError)
	{
		CLog::WriteLine("Failed"); 
		return E_FAIL; 
	}
}
HRESULT	CDInput9Device::UpdateMouse(void)
{
	Vector2i::zero(&m_mouseDelta); 
	
	if(ISNULL(m_pMouseDevice))
	{
		if(FAILED(ReleaseMouseDevice()) || FAILED(CreateMouseDevice()))
			return E_FAIL; 
	}

	DWORD dwElements = MOUSE_BUFFER_SIZE; 
	if(FAILED(m_pMouseDevice->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), m_mouseDataBuffer, &dwElements, 0)))
	{
		if(FAILED(m_pMouseDevice->Acquire()))
			return E_FAIL; 
	}

	for(unsigned int i = 0;  i < dwElements;  i++)
	{
		switch(m_mouseDataBuffer[i].dwOfs)
		{
			case DIMOFS_X:
				{
					m_mouseDelta.x = (int)m_mouseDataBuffer[i].dwData; 
					m_mousePos.x += m_mouseDelta.x; 
					CEngine::GetInstance()->GetWindow()->CenterCursor(); 
					break; 
				}

			case DIMOFS_Y:
				{
					m_mouseDelta.y = (int)m_mouseDataBuffer[i].dwData; 
					m_mousePos.y += m_mouseDelta.y; 
					CEngine::GetInstance()->GetWindow()->CenterCursor(); 
					break; 
				}

			case DIMOFS_Z:
				m_mouseWheel = (int) m_mouseDataBuffer[i].dwData; 
				break; 

			case DIMOFS_BUTTON0:
				{
					if(m_mouseDataBuffer[i].dwData & 0x80) m_mouseBut[0] = MOUSE_DOWN; 
					if(!(m_mouseDataBuffer[i].dwData & 0x80)) m_mouseBut[0] = MOUSE_UP; 
				}
				break; 

			case DIMOFS_BUTTON1:
				{
					if(m_mouseDataBuffer[i].dwData & 0x80) m_mouseBut[2] = MOUSE_DOWN; 
					if(!(m_mouseDataBuffer[i].dwData & 0x80)) m_mouseBut[2] = MOUSE_UP; 
				}
				break; 

			case DIMOFS_BUTTON2:
				{
					if(m_mouseDataBuffer[i].dwData & 0x80) m_mouseBut[1] = MOUSE_DOWN; 
					if(!(m_mouseDataBuffer[i].dwData & 0x80)) m_mouseBut[1] = MOUSE_UP; 
				}
				break; 
		}
	}

	return S_OK; 
}

void CDInput9Device::ResetMouseState()
{
	m_mouseWheel = 0; 
	m_mouseBut[0] = 0; 
	m_mouseBut[1] = 0; 
	m_mouseBut[2] = 0; 

	Vector2i::zero(&m_mousePos); 
}
